package com.xxx.control.activity

import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.widget.Button
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.AppCompatImageView
import com.blankj.utilcode.util.DeviceUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.ThrowableUtils
import com.blankj.utilcode.util.TimeUtils
import com.gg.reader.api.protocol.gx.MsgAppSetGpo
import com.github.forjrking.image.loadImage
import com.xxx.control.R
import com.xxx.control.adapter.MsgGoodsAdapter
import com.xxx.control.application.App
import com.xxx.control.application.SetInfo
import com.xxx.control.base.NoViewModel
import com.xxx.control.base.createApi
import com.xxx.control.base.ext.clickWithTrigger
import com.xxx.control.base.ext.dataConvert
import com.xxx.control.base.ext.getApiService
import com.xxx.control.base.launch
import com.xxx.control.bean.GoodsInfo
import com.xxx.control.bean.MsgBean
import com.xxx.control.bean.TagInfo
import com.xxx.control.constant.Constant
import com.xxx.control.databinding.ActivityHomeBinding
import com.xxx.control.net.ApiService
import com.xxx.control.utils.AlarmReceiver
import com.xxx.control.utils.AlarmUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import com.xxx.control.utils.ReaderClient
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import java.util.Properties

class HomeActivity : RFIDReadActivity<ActivityHomeBinding, NoViewModel>() {

    private var repeatCnt = 0

    private var msgGoodsAdapter = MsgGoodsAdapter()

    private val msgList = mutableListOf<MsgBean>()

    private var readNum = 0

    private val displayTagMap = mutableMapOf<String, Long>()

    private var lastReadTagTime = 0L

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化
        initView()
    }

    // 初始化
    private fun initView(){

//        EventBus.getDefault().register(this)
        getTime()
        readNum = SPUtils.getInstance().getInt(Constant.READER_NUM, 0)
        mBinding.tvOutGoods.text = "读取数：$readNum"

        mBinding.ivCircleL.loadImage(R.mipmap.gif_circle, isAnim = true)
        mBinding.ivCircleR.loadImage(R.mipmap.gif_circle, isAnim = true)

        val app = application as App

        initRv()
//        addMsg(NetworkUtils.getIPAddress(true))
        addMsg(TimeUtils.getNowString() + " - " + "读写器连接中...")
        launch({
            withContext(Dispatchers.IO) {
                startGetWork(app.client)
                startGetWork(app.clientSecond)
            }
        })
//        startGetWork()

        mBinding.tvReaderStatus.clickWithTrigger {
            startGetWork(app.client)
            startGetWork(app.clientSecond)
        }
        mBinding.ivSetting.clickWithTrigger {
            startActivity(SettingActivity::class.java)
        }

        // 第一次启动
        checkAndClean()

        val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
        mBinding.tvInCnt.text =  prefs.getInt("inCount",0).toString()
        mBinding.tvOutCnt.text = prefs.getInt("accumulateInCount",0).toString()

        inCount = prefs.getInt("inCount",0)
        accumulateinCount = prefs.getInt("accumulateInCount",0)

        mBinding.tvIpStatus.text = "工作模式：" + if (SetInfo.isOffline()) "离线" else "在线"


        findViewById<AppCompatImageView>(R.id.iv_setting).setOnClickListener {
            startActivityForResult(
                Intent(this, SettingActivity::class.java),
                REQUEST_CODE
            )
        }
    }

    private fun getTime() {
        launch({
            //间隔1s的循环 获取时间
            withContext(Dispatchers.IO) {
                while (true) {
                    //获取当前小时，分钟，秒钟
                    val time = TimeUtils.getNowString()
                    val hour = time.split(" ")[1].split(":")[0]
                    val minute = time.split(" ")[1].split(":")[1]
                    val second = time.split(" ")[1].split(":")[2]
                    //获取当前年月日一起
                    val year = time.split(" ")[0]
                    withContext(Dispatchers.Main) {
                        mBinding.date.text = "$year"
                        mBinding.tvHour.text = "$hour"
                        mBinding.tvMinute.text = "$minute"
                        mBinding.tvSecond.text = "$second"
                    }
                    Thread.sleep(60000)
                }
            }
        })
    }

    private fun initRv() {
        mBinding.rvGoods.adapter = msgGoodsAdapter
        msgGoodsAdapter.setNewInstance(msgList)
    }

    private fun addMsg(msg: String, isRed: Boolean = false) {
        runOnUiThread {
            if (msgList.size > 15) {
                msgGoodsAdapter.removeAt(15)
            }
            msgGoodsAdapter.addData(0, MsgBean(msg, isRed))
            mBinding.rvGoods.scrollToPosition(0)
//            msgList.add(0, MsgBean(msg, isRed))
//            msgGoodsAdapter.notifyDataSetChanged()
        }
    }

    override fun onDestroy() {
        val app = application as App
        app.client.close()
        app.clientSecond.close()
        super.onDestroy()
    }

    override fun onDataReceived(tagInfoList: MutableList<TagInfo>?) {

    }

    private val REQUEST_CODE = 100

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
            // 保存设置的时间
            AlarmUtils(this).apply {
                setDailyAlarm(SPUtils.getInstance().getInt(Constant.CURRENT_HOUR), SPUtils.getInstance().getInt(Constant.CURRENT_MINUTE))
            }
        }
    }

    override fun onTagReceived(name : String,tagInfo: TagInfo?) {

//        getBook()
        val now = System.currentTimeMillis()
        if (now - lastReadTagTime > 2000) {
            displayTagMap.clear()
        }
        lastReadTagTime = now
        if (tagInfo != null) {
            if (displayTagMap.containsKey(tagInfo.epc)) {
                if (now - (displayTagMap[tagInfo.epc] ?: 0) < 2000) {
                    LogUtils.file("EPC:${tagInfo.epc},2s内重复读取,不重复显示")
                    return
                } else {
                    LogUtils.file("EPC:${tagInfo.epc}, ${now - (displayTagMap[tagInfo.epc] ?: 0)}重复显示")
                }
            }
            addDisplayTagMap(tagInfo.epc)
//            addMsg(TimeUtils.getNowString() + " - " + "读到标签：" + tagInfo.epc)
            if (SetInfo.isOffline()) {
                addMsg(TimeUtils.getNowString() + " - " + tagInfo.epc)
                refreshReadNum()
            } else {
                getGoodInfo(name,tagInfo)
            }
        }

    }

    private fun getGoodInfo(name : String,tagInfo: TagInfo) {
        launch({
            LogUtils.e("EPC信息: ${tagInfo.epc}:${tagInfo.tid}")
            val info = createApi(ApiService::class.java).getInfo(
                mapOf(
                    "eid" to tagInfo!!.tid
                )
            ).dataConvert()
            if (info.id.isNullOrEmpty()) {
                addMsg(TimeUtils.getNowString() + " - " + tagInfo.epc)
            } else {
                addMsg(TimeUtils.getNowString() + " - " + info.daName, info.borrowStatus != 4)
                addAlarming(info)
                if (info.borrowStatus != 4) {
                    goAlarming(name,info)
                }
            }
            refreshReadNum()
        }, {
            LogUtils.e("Ex: " + ThrowableUtils.getFullStackTrace(it))
            addMsg(TimeUtils.getNowString() + " - " + tagInfo.epc)
            refreshReadNum()
        })
    }

    private fun addDisplayTagMap(epc: String) {
        val time = System.currentTimeMillis()
        displayTagMap[epc] = time
    }

    private fun refreshReadNum() {
        readNum++
        SPUtils.getInstance().put(Constant.READER_NUM, readNum)
        mBinding.tvOutGoods.text = "读取数：$readNum"
    }

    private var isAlarming = false
    private var isSecondAlarming = false
    private val alarmingTime = 2

    private fun goAlarming(name : String,info: GoodsInfo) {
        val app = application as App
        if(name == "readerA"){
            //正在警报   读取未结束
            if (isAlarming) {
                return
            }
            Thread {
                try {
                    isAlarming = true
                    //                            FileUtils.writeLog("开始报警");
                    LogUtils.e("触发报警：$name" )
                    val msgAppSetGpo = MsgAppSetGpo()
                    msgAppSetGpo.gpo1 = 1
//                msgAppSetGpo.gpo2 = 1
                    app.client.sendSynMsg(msgAppSetGpo)
                    Thread.sleep((1000 * alarmingTime).toLong())
                    val msgAppSetGpo2 = MsgAppSetGpo()
                    msgAppSetGpo2.gpo1 = 0
//                msgAppSetGpo2.gpo2 = 0
                    app.client.sendSynMsg(msgAppSetGpo2)
                    LogUtils.e("停止报警 ：$name")
                    //                            FileUtils.writeLog("停止报警");
                    isAlarming = false
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }.start()
        }else if (name == "readerB"){
            //正在警报   读取未结束
            if (isSecondAlarming) {
                return
            }
            Thread {
                try {
                    isSecondAlarming = true
                    //                            FileUtils.writeLog("开始报警");
                    LogUtils.e("触发报警：$name" )
                    val msgAppSetGpo = MsgAppSetGpo()
                    msgAppSetGpo.gpo1 = 1
//                msgAppSetGpo.gpo2 = 1
                    app.clientSecond.sendSynMsg(msgAppSetGpo)
                    Thread.sleep((1000 * alarmingTime).toLong())
                    val msgAppSetGpo2 = MsgAppSetGpo()
                    msgAppSetGpo2.gpo1 = 0
//                msgAppSetGpo2.gpo2 = 0
                    app.clientSecond.sendSynMsg(msgAppSetGpo2)
                    LogUtils.e("停止报警：$name" )
                    //                            FileUtils.writeLog("停止报警");
                    isSecondAlarming = false
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }.start()
        }else{
            LogUtils.e("不做任何报警处理" )
        }
    }

    private fun addAlarming(info: GoodsInfo) {
        launch({
            getApiService().addAlarm(
                mapOf(
                    "daCode" to (info.daCode ?: ""),
                    "daName" to (info.daName ?: ""),
                    "result" to (if (info.borrowStatus == 4) 0 else 1),
                    "eid" to (info.eid ?: "")
                )
            )
        })
    }

    override fun onConnectError(name : String) {
        val app = application as App
        if (repeatCnt < 3) {
            addMsg(TimeUtils.getNowString() + " - " + "读写器连接失败")
            repeatCnt++
            Handler().postDelayed({
                LogUtils.file("onConnectError again$repeatCnt")
                if(name == "readerA"){
                    startGetWork(app.client)
                }else{
                    startGetWork(app.clientSecond)
                }
            }, 1000)
        } else {
            mBinding.tvReaderStatus.text = "读写器：连接失败"
            addMsg(TimeUtils.getNowString() + " - " + "读写器连接失败")
        }

    }

    override fun onConnectSuccessed() {
        mBinding.tvReaderStatus.text = "读写器：连接成功"
        addMsg(TimeUtils.getNowString() + " - " + "读写器连接成功")
    }

    override fun onGpiStart(alarm: Int) {
        runOnUiThread {
            mBinding.tvInCnt.text = inCount.toString()
            mBinding.tvOutCnt.text = accumulateinCount.toString()
            if(alarm == 1){
                inoutAdd(inCount)
            }

            val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
            prefs.edit().putInt("inCount", inCount).apply()
            prefs.edit().putInt("accumulateInCount", accumulateinCount).apply()
        }
    }

    private fun inoutAdd(i: Int) {//0出 1进
        launch({
            getApiService().addInOut(
                mapOf(
                    "inoutDirection" to "in",
//                    "inoutTime" to TimeUtils.getNowString(),
                    "guardIp" to NetworkUtils.getIPAddress(true),
                    "guardName" to DeviceUtils.getUniqueDeviceId(),
                    "total" to i.toString()
                )
            )
        })
    }

    override fun onResume() {
        super.onResume()
        isGPI1IsIn = SPUtils.getInstance().getBoolean(Constant.DIRE_IN_ONE_TO_ZERO, false)
    }

    // 判断是否第一次启动
    private fun checkAndClean(){

        val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
        val lastDate = prefs.getString("lastDate", getCurrentDateString())

        LogUtils.e("最后日期：${lastDate}")
        // 当前日期
        val currentDate = getCurrentDateString()
        if (lastDate != currentDate) {
            val prefs = getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
            // 日期不一致，清空当今日进馆数
            prefs.edit().putInt("inCount", 0).apply()
        }

        // 更新最后启动日期
        prefs.edit().putString("lastDate", getCurrentDateString()).apply()

    }

    private fun getCurrentDateString(): String {
        return SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(Date())
    }
}